package br.urca.controller;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.TimeZone;

import javax.inject.Inject;
import javax.servlet.ServletContext;

import br.com.caelum.vraptor.Controller;
import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.jasperreports.Report;
import br.com.caelum.vraptor.jasperreports.download.ReportDownload;
import br.com.caelum.vraptor.jasperreports.formats.ExportFormats;
import br.com.caelum.vraptor.observer.download.Download;
import br.urca.dao.AlunosCursoDAO;
import br.urca.dao.AproveitamentoDAO;
import br.urca.dao.AtividadeAlunoDAO;
import br.urca.dao.CursoTurnoDAO;
import br.urca.dao.DisciplinaDAO;
import br.urca.dao.DisciplinasCursadasDAO;
import br.urca.dao.DisciplinasMatriculadasDAO;
import br.urca.dao.DocumentoEmitidoDAO;
import br.urca.dao.EquivalenciaDAO;
import br.urca.dao.FormaIngressoDAO;
import br.urca.dao.GradeCursoDAO;
import br.urca.dao.HabilitacaoDAO;
import br.urca.dao.HistoricoDAO;
import br.urca.dao.OfertaDAO;
import br.urca.dao.SituacaoDisciplinaDAO;
import br.urca.helper.HistoricoAluno;
import br.urca.http.ProtocoloCursoTurnoHTTP;
import br.urca.interceptor.InterceptResource;
import br.urca.model.AlunoCurso;
import br.urca.model.Aproveitamento;
import br.urca.model.AtividadeAluno;
import br.urca.model.CoeficienteDeRendimento;
import br.urca.model.Disciplina;
import br.urca.model.DisciplinaCursada;
import br.urca.model.DisciplinaMatriculada;
import br.urca.model.DocumentoEmitido;
import br.urca.model.DocumentoEmitidoPK;
import br.urca.model.GradeCurso;
import br.urca.model.GradeCursoPK;
import br.urca.model.HabilitacaoPK;
import br.urca.model.Historico;
import br.urca.model.HistoricoDisciplina;
import br.urca.model.Oferta;
import br.urca.model.protocolo.ProtocoloCursoTurno;
import br.urca.report.AbstractReport;
import br.urca.session.UsuarioLogado;
import br.urca.util.AutenticacaoDocumento;
import br.urca.util.ETipoDocumento;
import br.urca.util.Maiuscula;
import br.urca.util.Criptografia;
import br.urca.util.Utils;

@Controller
@InterceptResource
public class RelatorioHistoricoController {
	
	public static final String CURSANDO = "CURSANDO";
	
	private DisciplinasCursadasDAO mCursadasDAO;
	private DisciplinasMatriculadasDAO mMatriculadasDAO;
	private DisciplinaDAO mDisciplinaDAO;
	private OfertaDAO mOfertaDAO;
	private AlunosCursoDAO mCursoDAO;
	private DocumentoEmitidoDAO mEmitidosDAO;
	private GradeCursoDAO mGradeCursoDAO;
	private AtividadeAlunoDAO mAtividadeAlunoDAO;
	private HistoricoDAO mHistoricoDAO;
	private AproveitamentoDAO mAproveitamentoDAO;
	private FormaIngressoDAO mFormaIngressoDAO;	
	private UsuarioLogado mUsuarioLogado;
	private HabilitacaoDAO mHabilitacaoDAO;
	private EquivalenciaDAO mEquivalenciaDAO;
	private CursoTurnoDAO mCursoTurnoDAO;
	private SituacaoDisciplinaDAO mSituacaoDisciplinaDAO;
	private ServletContext context;
	private Result result;
	
	public RelatorioHistoricoController() { }
	
	@Inject
	public RelatorioHistoricoController(DisciplinasCursadasDAO mCursadasDAO,
			DisciplinasMatriculadasDAO mMatriculadasDAO,
			HabilitacaoDAO mHabilitacaoDAO, UsuarioLogado mUsuarioLogado,
			FormaIngressoDAO mFormaIngressoDAO, HistoricoDAO mHistoricoDAO,
			AtividadeAlunoDAO mAtividadeAlunoDAO, GradeCursoDAO mGradeCursoDAO,
			DisciplinaDAO mDisciplinaDAO, OfertaDAO mOfertaDAO,
			SituacaoDisciplinaDAO mSituacaoDisciplinaDAO,  AlunosCursoDAO mCursoDAO,
			AproveitamentoDAO mAproveitamentoDAO, EquivalenciaDAO mEquivalenciaDAO,
			DocumentoEmitidoDAO mEmitidosDAO, CursoTurnoDAO mCursoTurnoDAO,
			ServletContext context, Result result) {
		super();
		this.mCursadasDAO = mCursadasDAO;
		this.mMatriculadasDAO = mMatriculadasDAO;
		this.mDisciplinaDAO = mDisciplinaDAO;
		this.mOfertaDAO = mOfertaDAO;
		this.mCursoDAO = mCursoDAO;
		this.mEmitidosDAO = mEmitidosDAO;
		this.mGradeCursoDAO = mGradeCursoDAO;
		this.mAtividadeAlunoDAO = mAtividadeAlunoDAO;
		this.mHistoricoDAO = mHistoricoDAO;
		this.mAproveitamentoDAO = mAproveitamentoDAO;
		this.mFormaIngressoDAO = mFormaIngressoDAO;
		this.mUsuarioLogado = mUsuarioLogado;
		this.mHabilitacaoDAO = mHabilitacaoDAO;
		this.mEquivalenciaDAO = mEquivalenciaDAO;
		this.mCursoTurnoDAO = mCursoTurnoDAO;
		this.mSituacaoDisciplinaDAO = mSituacaoDisciplinaDAO;
		this.context = context;
		this.result = result;
	}

	@Get("/historico/pdf")
	public Download historico(String matricula) {
		
		try {
			if (matricula != null) {
				
				HistoricoAluno mHistoricoAluno = new HistoricoAluno(
						mCursadasDAO, mMatriculadasDAO, mHabilitacaoDAO,
						mUsuarioLogado, mHistoricoDAO, mAtividadeAlunoDAO,
						mGradeCursoDAO, mDisciplinaDAO, mOfertaDAO,
						mSituacaoDisciplinaDAO, mCursoDAO, mAproveitamentoDAO,
						mEquivalenciaDAO, mEmitidosDAO, true);
				
				mHistoricoAluno.processarInformacoesDoAluno(matricula);

				//Pega os dados do aluno
				AlunoCurso alunoCurso = mCursoDAO.buscaPorMatricula(matricula);
				
				List<HistoricoDisciplina> mListDisciplinas = new ArrayList<HistoricoDisciplina>();
				mListDisciplinas.clear();
				mListDisciplinas.addAll(mHistoricoAluno.getListDisciplinas());
	
				
				if ((mListDisciplinas != null) && (alunoCurso != null)) {
					
					//Gerar o código de veracidade do documento
					AutenticacaoDocumento mAutenticacao = new AutenticacaoDocumento(matricula, ETipoDocumento.HISTORICO);
					
					//Pegando informações da grade
					GradeCurso gradeCurso = mGradeCursoDAO
							.getGradePorId(new GradeCursoPK(alunoCurso
									.getCurso().getCodCurso(), alunoCurso
									.getHabilitacao(), alunoCurso.getGrade(),
									alunoCurso.getTurma()));
					
					//Calculando total de horas exigidas
					int totalCHExigida = ((gradeCurso.getTotalCreditos() * 15)
								+ (gradeCurso.getTotalCredAtivCompl() * 15) 
								+ (gradeCurso.getTotalCredPraticaCompCurr() * 15));
					
					
					Historico histPratCurrComp = mHistoricoDAO.getPraticasCompCurr(matricula);	
					
					
					ProtocoloCursoTurno pct = ProtocoloCursoTurnoHTTP
							.getReconhecimentoProtocolo(
									Utils.KEY_APPLICATION,
									alunoCurso.getCodCursoTurno());
					
					//Criando relatório
			        Report report = new AbstractReport(mListDisciplinas, "historico.jasper", "hitorico_");
			        String realPath = context.getRealPath("/WEB-INF/reports/images/");		        
					report.addParameter("realPath", realPath);
					report.addParameter("matricula", matricula);
					report.addParameter("aluno", alunoCurso.getAluno().getNome());
					
					report.addParameter("formaIngresso", Maiuscula.parse((mFormaIngressoDAO
							.getByCodigo(matricula.substring(5, 6))
							.getDescricao()).toLowerCase()));
					
					report.addParameter("curso", mHistoricoAluno.
							getHabilitacaoAluno(new HabilitacaoPK(
									alunoCurso.getCurso().getCodCurso(),
									alunoCurso.getHabilitacao())) + 
									Maiuscula.parse(alunoCurso.getCurso().getNomeCurso().toLowerCase()));
					
					report.addParameter("turno", mHistoricoAluno.getDescricaoTurno(mCursoTurnoDAO.buscarPorCursoTurno(alunoCurso.getCodCursoTurno(),
							alunoCurso.getCurso())));
					
					report.addParameter("situacaoAluno", alunoCurso.getSituacao().getDescricao());
					
					SimpleDateFormat formatador = new SimpleDateFormat("dd/MM/yyyy");
					
					if (alunoCurso.getAluno().getDtNascimento() != null) {
						report.addParameter("dataNascimento", formatador.format(alunoCurso.getAluno().getDtNascimento()));
					}
					
					report.addParameter("naturalidade",
							(alunoCurso.getAluno().getNaturalidade() != null ? Maiuscula.parse(alunoCurso.getAluno()
									.getNaturalidade().toLowerCase()) : " ") + " - " + 
									(alunoCurso.getAluno().getUfNascimento() != null ? alunoCurso.getAluno().getUfNascimento() : " " ));
					
					report.addParameter("identidade", ( alunoCurso.getAluno().getRg() != null ? alunoCurso.getAluno().getRg() : " " ) 
							+ " / " + ( alunoCurso.getAluno().getOrgaoExpeditor() != null ? alunoCurso.getAluno().getOrgaoExpeditor() : " " )
							+ " - " + ( alunoCurso.getAluno().getUfIdentidade() != null ? alunoCurso.getAluno().getUfIdentidade() : " " ));
					
					report.addParameter("reconhecimento",
							(pct.getReconhecimentoIntegral() != null ? pct
									.getReconhecimentoIntegral() : alunoCurso
									.getCurso().getReconhecimentoMEC()));
					
					report.addParameter("grade", alunoCurso.getGrade());
										
					String nomePai = (alunoCurso.getAluno().getNomePai() != null ? Maiuscula.parse(alunoCurso.getAluno().getNomePai().toLowerCase()) : " ");
					String nomeMae = (alunoCurso.getAluno().getNomeMae() != null ? Maiuscula.parse(alunoCurso.getAluno().getNomeMae().toLowerCase()) : " ");
					report.addParameter("filiacao", nomePai + (nomePai != " " ? "  e  " : "") + nomeMae);
	
					//Carga horária exigida
					report.addParameter("disciObrigExig", gradeCurso.getTotalCreditos());
					report.addParameter("ativCompExig", gradeCurso.getTotalCredAtivCompl());
					report.addParameter("pratCompCurrExig", gradeCurso.getTotalCredPraticaCompCurr());
					report.addParameter("totalCHExig", totalCHExigida);
					
					//Carga horária obtida
					report.addParameter("disciObrigObtido", mHistoricoAluno.getTotalCredDiscObg()); 
					report.addParameter("ativCompObtido", mHistoricoAluno.getTotalAtivCompObtida());
					report.addParameter("pratCompCurrObtido",  (histPratCurrComp != null ? histPratCurrComp.getCreditos() : 0) 
							+ mHistoricoAluno.getTotalPartCompCurr());
					report.addParameter("totalCHObtido", mHistoricoAluno.getTotalCHObtida());
					report.addParameter("credEdFisica", mHistoricoAluno.getTotalCredEdFisica()); 
					
					
					//Coeficiente de rendimento
					report.addParameter("rendimento", mHistoricoAluno.getCoeficienteRendimento(matricula)); 
	
			        report.addParameter("md5", mAutenticacao.getAutenticacao());
			        report.addParameter("validacao", mAutenticacao.getHash());
			        
			        //if (salvarEmissaoDeHistorico(matricula, mAutenticacao.getHash())) {
			        	return new ReportDownload(report, ExportFormats.pdf(), false);
			        //} else {
			        //	throw new Exception("Falha ao tentar salvar o relatório!");
			        //}
				}//Fim if
			}//Fim if
		} catch(Exception e) {
			result.include("mensagem","Desculpe! Não foi possível gerar o relatório!"
					+ " Tente novamente mais tarde ou entre em contato com o D.T.I. da Urca." + e.getMessage())
				.redirectTo(ConsultaMatriculaController.class).index();
			return null;
		}
		return null;
	}
	
	
	
}
